/*******************************************************************************
  Copyright(c) 2009 Geoffrey Hausheer. All rights reserved.

  This program is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the Free
  Software Foundation; either version 2 of the License, or (at your option)
  any later version.

  This program is distributed in the hope that it will be useful, but WITHOUT
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  more details.

  You should have received a copy of the GNU General Public License along with
  this program; if not, write to the Free Software Foundation, Inc., 59
  Temple Place - Suite 330, Boston, MA  02111-1307, USA.

  The full GNU General Public License is included in this distribution in the
  file called LICENSE.

  Contact Information: dso-tonight-at-phracturedblue-dot-com
*******************************************************************************/

package dsotonight;

import java.util.Calendar;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author ghaushe
 */
public class SiderealDate {
    // Cal should be in local time
    // longitude in degrees
    public static double SiderealTime(double julianUTC, double lonW) {
        double delta, gmst, localst;

        delta = julianUTC - 2451545.0; //days since Jan 1, 2000 12:00 UST
        gmst = 18.697374558 + 24.06570982441908 * delta;
        localst = gmst - lonW / 360 * 24;
        localst = localst % 24;
        return localst;
    }

    public static double SiderealTime(Calendar cal, double lonW)
    {
        double julian_midnight, julian;
        julian_midnight = JulianDate.toJulian(new int []{cal.get(Calendar.YEAR), cal.get(Calendar.MONTH)+1, cal.get(Calendar.DATE)}) - 0.5;
        julian = julian_midnight +
                cal.get(Calendar.HOUR_OF_DAY) / 24.0 + cal.get(Calendar.MINUTE) / (24 * 60.0) + cal.get(Calendar.SECOND) / (24 * 3600.0);
        return SiderealTime(JulianDate.localToUTC(julian), lonW);

    }

    public static String RightAscensionToString(double ra) {
        int hour;
        int minute;
        double second;

        hour = (int) ra;
        minute = (int)((ra - hour) * 60);
        second = (ra - hour)* 3600 - (minute * 60);
        return String.format("%d:%d:%05.2f", hour, minute, second);
    }
    public static double stringToDouble(String items[]){
        if(items.length == 1) {
            try {
                return Double.parseDouble(items[0]);
            } catch (Exception e) {
                return Double.NaN;
            }
        }
        if(items.length == 2) {
            try {
                int hour   = Integer.parseInt(items[0]);
                double min = Double.parseDouble(items[1]);
                return hour + min / 60.0;
            } catch (Exception e) {
                return Double.NaN;
            }
        }
        if(items.length == 3) {
            try {
                int hour   = Integer.parseInt(items[0]);
                int min    = Integer.parseInt(items[1]);
                double sec = Double.parseDouble(items[2]);
                return hour + min / 60.0 + sec / 3600.0;
            } catch (Exception e) {
                return Double.NaN;
            }
        } else {
            return Double.NaN;
        }

    }

    public static double stringToRightAscension(String str) {
        Double ret;

        str.replaceAll("[\\s:]+", ":");
        String items[] = str.split(":");
        ret = stringToDouble(items);
        if (ret.isNaN() || ret < 0 || ret > 24) {
            return Double.NaN;
        }
        return ret;
    }

    public static String DeclinationToString(double dec) {
        int degrees;
        int minute;
        double second;

        degrees = (int) dec;
        minute = (int)((dec - degrees) * 60);
        second = (dec - degrees)* 3600 - (minute * 60);
        return String.format("%d %d %05.2f", degrees, minute, second);
    }

    public static double stringToDeclination(String str) {
        double ret;

        str = str.replaceAll("[\\s:\'\"]+", ":");
        String items[] = str.split(":");
        ret = stringToDouble(items);
        if (ret == Double.NaN || ret < -90 || ret > 90) {
            return Double.NaN;
        }
        return ret;
    }
    public static double stringToLongitude(String str) {
        double ret;
        str = str.replaceAll("[\\s:\'\"]+", ":");
        String items[] = str.split(":");
        ret = stringToDouble(items);
        if (ret == Double.NaN || ret < -180 || ret > 180) {
            return Double.NaN;
        }
        return ret;
    }
    
    public static int Minutes(double val) {
        return (int)Math.abs((val - (int)val) * 60.0);
    }
    public static double Seconds(double val) {
        val = val * 60;
        return Math.abs((val - (int)val) * 60.0);
    }
}
